package main

import "fmt"

type student struct {//创建一个学生的结构体
	Name string //结构体的属性，姓名
	Age int //结构体属性，年龄
}
func pase_student() map[string]*student{ //创建函数,返回的是map[key string]value 结构体指针
	m:=make(map[string]*student) //创建一个map对象map[]
	stus:=[]student{ //创建student结构体对象，并给这个结构体赋值map
		{Name:"zhou",Age:24},//0
		{Name:"li",Age:23}, //1
		{Name:"wang",Age:22}, //2
	}

	fmt.Println("stus的值：",stus) //[{zhou 24} {li 23} {wang 22}
	fmt.Println("-------------")
	for i,_ :=range stus{ //遍历stus结构体对象,stu是每个map的值，有name和age
		stu:=stus[i] //0,0xc42000a100 |1,0xc42000a140|2,0xc42000a180
		m[stu.Name]=&stu //0,0xc42000a100 &{zhou 24} |1,0xc42000a140 &{li 23}|2,0xc42000a180 &{wang 22}
		//把值用指针重新赋值给map,但是有个问题，&stu实际上指向的是同一个指针，所以每次赋值都会改变同一个地址中的数据，
		//所以会把最后range的值赋值到指针地址0xc42000a100中,最后只有一个数据wang 22
		//解决方法：stu:=stus[i] //按下标取值0{zhou 24} 1{li 23} 2{wang 22},取出的值赋值给stu，这样stu的就变成值拷贝了。stu的地址都不一样
		//range的stu变量不要加。
		fmt.Printf("%p\n",&stu) //&stu的地址都是相同0xc42000a100

	}
	fmt.Println(m)
	return m //map[zhou:0xc42000a100 li:0xc42000a120 wang:0xc42000a140]

}
func main()  {
	students:= pase_student()
	fmt.Println("students:",students) //返回students: map[zhou:0xc42000a100 li:0xc42000a120 wang:0xc42000a140]
	fmt.Println(students["zhou"],students["li"],students["wang"]) //&{zhou 24} &{li 23} &{wang 22}
	for k,v :=range students{ //遍历，取出值
			fmt.Printf("key=%s,value=%v \n", k, v)
			/*
			key=zhou,value=&{zhou 24}
			key=li,value=&{li 23}
			key=wang,value=&{wang 22}
			*/
	}
}

/*
答：以上代码的问题出在&stu指针的值传递上，因为&stu指向的是同一个地址，所以无论传递多少值，最后都会用后面的值覆盖以前的值，因为一个内存地址只能存一个值。
所以解决方法是用下标遍历，把遍历的值赋值给stu变量 ，然后再将stu变量地址传递给m[stu.name]，每次都进行值传递，所以每次都会重新在内存中开辟新空间。
*/